package com.xinghanlaser.applet.base.flow.service.impl;

import com.xinghanlaser.applet.base.common.exception.ServiceException;
import com.xinghanlaser.applet.base.flow.core.IFlowService;
import com.xinghanlaser.applet.base.flow.core.PointHandleUtil;
import com.xinghanlaser.applet.base.flow.mapper.FlowLineStepMapper;
import com.xinghanlaser.applet.base.flow.vo.AccessPointVO;
import com.xinghanlaser.applet.base.flow.vo.PointQueryVO;
import com.xinghanlaser.applet.base.flow.vo.PointVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xinghanlaser.applet.base.flow.constant.PointConstant.EXCLUDE_VALIDATE_NEXT_POINT;

/**
 * <p>
 *
 * <p>
 *
 * @author: mftuo 陀铭峰
 * @since: 2024/5/17 17:35
 */
@Service
public class FlowServiceImpl implements IFlowService {
    @Resource
    private FlowLineStepMapper flowLineStepMapper;

    @Resource
    private PointHandleUtil pointHandleUtil;

    @Override
    public Set<PointVO> getNextPointListByCondition(PointQueryVO queryVO) {
        return flowLineStepMapper.getNextPointList(
                queryVO.getRoleId(),
                queryVO.getCurrentPointId(),
                queryVO.getLineTypeId()
        );
    }

    @Override
    public void nextPoint(AccessPointVO vo, Long currentPointId) {
        final Map<String, Object> pointData = vo.getPointData();
        final Long pointId = vo.getPointId();

        // 排除不用判断下一个节点能否被调用的逻辑
        if(EXCLUDE_VALIDATE_NEXT_POINT.contains(pointId)){
            pointHandleUtil.executeCurrentPoint(pointData, pointId);
            return;
        }

        // 判断下一个节点能否被调用
        validateNextPoint(vo, currentPointId);

        pointHandleUtil.executeCurrentPoint(pointData, pointId);
    }


    private void validateNextPoint(AccessPointVO vo, Long currentPointId){
        final Long pointId = vo.getPointId();
        final Integer lineTypeId = vo.getLineTypeId();
        final Long roleId = vo.getRoleId();

        Set<Long> nextPointId = flowLineStepMapper.getNextPointList(roleId, currentPointId, lineTypeId)
                .stream()
                .map(PointVO::getId)
                .collect(Collectors.toSet());

        if (!nextPointId.contains(pointId)){
            throw new ServiceException("节点顺序错误");
        }
    }
}
